#include <Arduino.h>
#include "XL9555.h"
#include "Timer.h"
#include "24c02.h"
// #include "OLED.h"
#include "LCD.h"
#define LED_PIN 1
#define BOOT 0

#define LED_TURN() digitalWrite(LED_PIN,!digitalRead(LED_PIN));

int8_t R = 0,G = 0,B = 0;

uint8_t pos = 3;    //更改值的位置

bool flash_RGB = 0;
bool Rainbow = 0;
uint8_t EEPROM_addr = 0x88;
int8_t *EEPROM_data[3] = {&R,&G,&B};

LedcPwm ledc(LED_PIN,0,10000,(uint8_t)8);

void RGB_save();
void RGB_load();
void fill_RGB();
uint16_t rgb565();
void LED_breathe();
void RGB_change(int8_t change);

void setup()
{
    //pinMode(LED_PIN,OUTPUT);
    pinMode(BOOT,INPUT_PULLUP);
    //OLED_Init();
    //Serial.begin(115200);
    {
        at24c02_init();           /* 初始化24CXX */
        while (at24c02_check()==false)   /* 检测不到24c02 */
        {
            Serial.println("24C02 Check Failed!");
            delay(500);
        }
        Serial.println("24C02 Ready!");
    }

    RGB_load();

    {
        xl9555_init();
        xl9555_io_config(KEY0 | KEY1 | KEY2 | KEY3, IO_SET_INPUT); 
        //xl9555_io_config(BEEP, IO_SET_OUTPUT); 
    }

    lcd_init();             /* LCD初始化 */
    lcd_show_string(spilcd_width - 16*10, spilcd_height - 24*3,LCD_FONT_24, "RED:   0x", RED);
    lcd_show_string(spilcd_width - 16*10, spilcd_height - 24*2,LCD_FONT_24, "GREEN: 0x", GREEN);
    lcd_show_string(spilcd_width - 16*10, spilcd_height - 24*1,LCD_FONT_24, "BLUE:  0x", BLUE);

    lcd_show_string(180 - 8*2,150 - 8*2,LCD_FONT_16,"0X",BLACK);
}

void loop() 
{
    LED_breathe();

    if(flash_RGB){
        fill_RGB();
        lcd_fill(180,150 - 8*2, 180 + 8*4, 150, WHITE);
        RGB_save();
        flash_RGB = false;
    }

    lcd_show_hexNum(spilcd_width - 16*3, spilcd_height - 24*3,
        R,2,LCD_FONT_24,NUM_SHOW_ZERO,RED);
    lcd_show_hexNum(spilcd_width - 16*3, spilcd_height - 24*2,
        G,2,LCD_FONT_24,NUM_SHOW_ZERO,GREEN);
    lcd_show_hexNum(spilcd_width - 16*3, spilcd_height - 24*1,
        B,2,LCD_FONT_24,NUM_SHOW_ZERO,BLUE);

    if(xl9555_get_pin(KEY3) == 0){
        delay(10);
        while(xl9555_get_pin(KEY3) == 0);
        pos++;
        pos = pos > 3 ? 1:pos;
    }
    else if(xl9555_get_pin(KEY1) == 0){
        delay(10);
        while(xl9555_get_pin(KEY1) == 0);
        pos--;
        pos = pos < 1 ? 3:pos;
    }

    for(uint8_t i = 3; i > 0; i--){
        if(i == pos) continue;
        lcd_draw_rectangle(spilcd_width - 16*5, spilcd_height - 24*i,
            spilcd_width - 16*1 - 4, spilcd_height - 24*(i-1) - 1,WHITE);
    }

    lcd_draw_rectangle(spilcd_width - 16*5, spilcd_height - 24*pos,
        spilcd_width - 16*1 - 4, spilcd_height - 24*(pos-1) - 1,BLACK);

    if(xl9555_get_pin(KEY0) == 0){
        delay(20);
        RGB_change(1);
    }else if(xl9555_get_pin(KEY2) == 0){
        delay(20);
        RGB_change(-1);
    }else if(digitalRead(BOOT) == 0){
        delay(50);
        Rainbow = !Rainbow;
    }
    
    lcd_show_hexNum(180,150 - 8*2,
        rgb565(),4,LCD_FONT_16,NUM_SHOW_ZERO,BLACK);

    lcd_fill_circle(90, 90, 60, rgb565());
    
    if (Rainbow) {
            R++;
            pos = 3;
            if (R >= 0x1F) {
                fill_RGB();
                R = 0;
                G++;
                pos = 2;
                if (G >= 0x3F) {
                    fill_RGB();
                    G = 0;
                    B++;
                    pos = 1;
                    if (B >= 0x1F) {
                        B = 0;
                    }
                }
            }
            flash_RGB = true;
    }
}

void fill_RGB(){
    lcd_fill(spilcd_width - 16*3 - 1, spilcd_height - 24*pos + 1,
        spilcd_width - 16*1 - 5, spilcd_height - 24*(pos-1) - 2,WHITE);
}

void LED_breathe()
{
    static int16_t val;
    static bool dir;
    val += (dir ? 8 : -8);
    dir = ((val+8) >= 255 ?  0 : dir);
    dir = ((val-8) <= 0 ? 1 : dir);
    ledc.ledcpwm_write(val);
}

void RGB_save()
{
    for(uint8_t i = 0; i < 3; i++)
    {
        at24c02_write_one_byte(EEPROM_addr + i, (uint8_t )*EEPROM_data[i]);
    }
}

void RGB_load()
{
    for(uint8_t i = 0; i < 3; i++)
    {
        *EEPROM_data[i] = (int8_t)at24c02_read_one_byte(EEPROM_addr + i);
    }
}

void RGB_change(int8_t change)
{
    switch(pos)
    {
        case 3:
            R += change;
            if(R > 0x1F) R = 0;
            if(R < 0) R = 0x1F;
            break;
        case 2:
            G += change;
            if(G > 0x3F) G = 0;
            if(G < 0) G = 0x3F;
            break;
        case 1:
            B += change;
            if(B > 0x1F) B = 0;
            if(B < 0) B = 0x1F;
            break;
    }

    flash_RGB = true;
}

//RGB 565
uint16_t rgb565()
{
    return (R << 11) | (G << 5) | B;
}
